package es

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"github.com/elastic/go-elasticsearch/v7"
	"github.com/elastic/go-elasticsearch/v7/esapi"
	"log"
	"srv/model/mysql"
	"srv/srv"
	"strconv"
	"sync"
)

var (
	Es *elasticsearch.Client
	wg sync.WaitGroup
)

func EsConfig() {
	var err error
	cfg := elasticsearch.Config{
		Addresses: []string{
			"http://14.103.169.25:9200",
		},
		// ...
	}
	Es, err = elasticsearch.NewClient(cfg)
	if err != nil {
		fmt.Println("es连接失败")
		return
	}
	fmt.Println("es连接成功")
}

func EsAdd(good []mysql.Good) {
	for _, title := range good {
		wg.Add(1)
		go func(title mysql.Good) {
			defer wg.Done()
			// Build the request body.
			data, err := json.Marshal(title)
			if err != nil {
				log.Fatalf("Error marshaling document: %s", err)
			}

			// Set up the request object.
			req := esapi.IndexRequest{
				Index:      "goods",
				DocumentID: strconv.Itoa(int(title.ID)),
				Body:       bytes.NewReader(data),
				Refresh:    "true",
			}
			// Perform the request with the client.
			res, err := req.Do(context.Background(), Es)
			if err != nil {
				log.Fatalf("Error getting response: %s", err)
			}
			defer res.Body.Close()
		}(title)
	}
	wg.Wait()
}

func EsFind(goodName string) (good []*srv.EsFind) {
	var buf bytes.Buffer
	query := map[string]interface{}{}
	if goodName == "" {
		query = map[string]interface{}{
			"query": map[string]interface{}{
				"match_all": map[string]interface{}{},
			},
		}
	} else {
		query = map[string]interface{}{
			"query": map[string]interface{}{
				"match": map[string]interface{}{
					"GoodName": goodName,
				},
			},
		}
	}

	if err := json.NewEncoder(&buf).Encode(query); err != nil {
		log.Fatalf("Error encoding query: %s", err)
	}

	// Perform the search request.
	res, err := Es.Search(
		Es.Search.WithContext(context.Background()),
		Es.Search.WithIndex("goods"),
		Es.Search.WithBody(&buf),
		Es.Search.WithTrackTotalHits(true),
		Es.Search.WithPretty(),
	)
	fmt.Println(res)
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	defer res.Body.Close()

	var r map[string]interface{}
	json.NewDecoder(res.Body).Decode(&r)
	for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) {
		m := hit.(map[string]interface{})["_source"].(map[string]interface{})
		GoodName := m["GoodName"].(string)
		GoodNum := m["GoodNum"].(string)
		GoodPrice := m["GoodPrice"].(float64)
		GoodStock := m["GoodStock"].(float64)
		GoodCollection := m["GoodCollection"].(float64)

		good = append(good, &srv.EsFind{
			GoodName:       GoodName,
			GoodNum:        GoodNum,
			GoodPrice:      float32(GoodPrice),
			GoodStock:      int64(GoodStock),
			GoodCollection: int64(GoodCollection),
		})
	}
	return
}
